package com.nx.platform.es.biz.query.agg.handler;


import com.google.common.base.Preconditions;
import com.google.common.collect.Table;
import com.nx.platform.es.biz.wrapper.parser.StatementOperator;
import com.nx.platform.es.biz.wrapper.parser.StatementParser;
import com.nx.platform.es.service.ESClientManager;
import com.nx.platform.es.system.config.ESQueryConfigure;
import com.nx.platform.es.bean.dto.ESQueryConfDTO;
import com.nx.platform.es.biz.query.agg.AggRequestContext;
import com.nx.platform.es.biz.wrapper.parser.StatementParsers;
import com.nx.platform.es.common.utils.MoreLists;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * 请求处理链实现
 * <p>
 * Created by  on 2017/4/18.
 */
public class AggRequestHandlerChainImpl implements AggRequestHandlerChain {

    private final StatementParser parser = StatementParsers.Default;
    private final List<AggRequestHandler> handlers = new LinkedList<>();

    private final ESClientManager clients;
    private final ESQueryConfigure configs;

    public AggRequestHandlerChainImpl(ESClientManager clients, ESQueryConfigure configs) {
        this.clients = clients;
        this.configs = configs;
    }

    @Override
    public void appendHandler(AggRequestHandler handler) {
        handlers.add(handler);
    }

    @Override
    public void handle(AggRequestContext context) {
        context.getTrace().append("_method=agg");
        prepare(context);
        for (AggRequestHandler handler : handlers) {
            handler.handle(context);
        }
    }

    private void prepare(AggRequestContext context) {

        ESQueryConfDTO config = configs.getESEntryConfig(context.getEntry());
        Preconditions.checkState(config != null, "unkown request entry(" + context.getEntry() + ")");
        Table<String, StatementOperator, List<String>> queryTable = parser.parse(context.getQuery());
        Table<String, StatementOperator, List<String>> paramsTable = parser.parse(context.getParams());
        Set<String> codes = config.getCluster();
        String targetClient = MoreLists.getFirst(queryTable.get("cluster", StatementOperator.EQUAL));
        ESClientManager.ESClient esClient = clients.getResource(codes, targetClient);
        Preconditions.checkState(esClient != null, "acquire es client resource error");

        context.setEsClient(esClient);
        context.getTrace().append("&_cluster=").append(esClient.getCode());
        context.setConfig(config);
        context.setQueryTable(queryTable);
        context.setParamsTable(paramsTable);
        context.setClient(esClient.getHosts());
        context.setIndex(config.getIndex());
        context.setType(config.getType());
        context.setTimeout(config.getTimeout());
        context.setQueryFields(config.getQueryFields());
        context.setAggFields(config.getAggFields());
        context.setExpireAfterWrite(config.getExpireAfterWrite());
        context.setUseRequestCache(config.isUseRequestCache());
        context.setRequest(new SearchRequest());
        context.getRequest().source(new SearchSourceBuilder());

    }

}
